package com.cowmooed.dto;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor // Jackson反序列化需要
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class DeviceInfoDTO {
    private String userAgent;
    private String platform;
    private String language;
    private ScreenInfo screen;
    private MemoryInfo memory;
    private GpuInfo gpu;
    private CpuInfo cpu;
    private NetworkInfo network;
    private PerformanceInfo performance;
    private DeviceTypeInfo deviceType;
    private BatteryInfo battery;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class ScreenInfo {
        private Integer width;
        private Integer height;
        private Integer availWidth;
        private Integer availHeight;
        private Integer colorDepth;
        private Integer pixelDepth;
        private Double devicePixelRatio;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class MemoryInfo {
        private Double deviceMemory;
        private Long usedJSHeapSize;
        private Long totalJSHeapSize;
        private Long jsHeapSizeLimit;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class GpuInfo {
        private Boolean webglSupported;
        private Boolean webgl2Supported;
        private String vendor;
        private String renderer;
        private String version;
        private String shadingLanguageVersion;
        private Integer maxTextureSize;
        private Integer maxRenderBufferSize;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class CpuInfo {
        private Integer cores;
        private String architecture;
        private EstimatedPerformance estimatedPerformance;

        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class EstimatedPerformance {
            private Double testDuration;
            private String performance; // high, medium, low
        }
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class NetworkInfo {
        private Boolean onLine;
        private String connectionType;
        private String effectiveType;
        private Double downlink;
        private Integer rtt;
        private Boolean saveData;
        private SpeedTest speedTest;

        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class SpeedTest {
            private Double latency;
            private String status;
            private String error;
        }
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class PerformanceInfo {
        private TimingInfo timing;
        private MemoryUsage memory;
        private NavigationInfo navigation;

        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class TimingInfo {
            private Long loadTime;
            private Long domReady;
            private Long connectTime;
        }

        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class MemoryUsage {
            private Long usedJSHeapSize;
            private Long totalJSHeapSize;
            private Long jsHeapSizeLimit;
        }

        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class NavigationInfo {
            private Integer type;
            private Integer redirectCount;
        }
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class DeviceTypeInfo {
        private Boolean isMobile;
        private Boolean isTablet;
        private Boolean isDesktop;
        private String type;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class BatteryInfo {
        private Boolean charging;
        private Double level;
        private Double chargingTime;
        private Double dischargingTime;
    }
}